{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第五次作业"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 0.载入图片"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "# 载入图片\n",
    "from PIL import Image,ImageStat\n",
    "import numpy as np\n",
    "import cv2 as cv\n",
    "img1 = Image.open('F:/data/image/1.jpg')\n",
    "img2 = Image.open('F:/data/image/2.jpg')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "img1 JPEG (1920, 1080) RGB\n",
      "img2 JPEG (1920, 1080) RGB\n"
     ]
    }
   ],
   "source": [
    "# 查看图片的性质\n",
    "print('img1',img1.format, img1.size, img1.mode)\n",
    "print('img2',img2.format, img2.size, img2.mode)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.平均哈希算法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 对图片进行缩放\n",
    "aHash_resize_width = 8\n",
    "aHash_resize_height = 8\n",
    "smaller_ahash_img1 = img1.resize((aHash_resize_width, aHash_resize_height))\n",
    "smaller_ahash_img2 = img2.resize((aHash_resize_width, aHash_resize_height))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "img1 None (8, 8)\n",
      "img2 None (8, 8)\n"
     ]
    }
   ],
   "source": [
    "# 查看图片大小\n",
    "print('img1',smaller_ahash_img1.format, smaller_ahash_img1.size)\n",
    "print('img2',smaller_ahash_img2.format, smaller_ahash_img2.size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 转换为灰度直方图\n",
    "grayscale_ahash_image1 = smaller_ahash_img1.convert(\"L\")\n",
    "grayscale_ahash_image2 = smaller_ahash_img2.convert(\"L\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 0 0 1 1 1\n",
      " 1 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 0 0 0 1 1 1 1\n",
      " 1 1 1 0 1 1 1 0 0 0 1 0 0 1 1 1 0 1 1 0 0 0 0 1 0 0 0]\n",
      "21\n"
     ]
    }
   ],
   "source": [
    "# 计算平均值\n",
    "grayscale_ahash_image1_stat = ImageStat.Stat(grayscale_ahash_image1)\n",
    "grayscale_ahash_image1_mean =grayscale_ahash_image1_stat.mean[0]\n",
    "\n",
    "grayscale_ahash_image2_stat = ImageStat.Stat(grayscale_ahash_image2)\n",
    "grayscale_ahash_image2_mean =grayscale_ahash_image2_stat.mean[0]\n",
    "\n",
    "# 比较像素灰度值：遍历灰度图片每一个像素，如果大于平均值记录为1 ，否则为0\n",
    "grayscale_ahash_image1_np = np.array(grayscale_ahash_image1)\n",
    "grayscale_ahash_image2_np = np.array(grayscale_ahash_image2)\n",
    "\n",
    "for x in range(8):\n",
    "    for y in range(8):\n",
    "        if grayscale_ahash_image1_np[x,y] >= grayscale_ahash_image1_mean:\n",
    "            grayscale_ahash_image1_np[x,y] = 1\n",
    "        else:\n",
    "            grayscale_ahash_image1_np[x,y] = 0\n",
    "            \n",
    "for x in range(8):\n",
    "    for y in range(8):\n",
    "        if grayscale_ahash_image2_np[x,y] >= grayscale_ahash_image2_mean:\n",
    "            grayscale_ahash_image2_np[x,y] = 1\n",
    "        else:\n",
    "            grayscale_ahash_image2_np[x,y] = 0\n",
    "\n",
    "# 计算汉明距离\n",
    "grayscale_ahash_image1_list = np.reshape(grayscale_ahash_image1_np,64)\n",
    "grayscale_ahash_image2_list = np.reshape(grayscale_ahash_image2_np,64)\n",
    "\n",
    "distance_hanming = 0\n",
    "for x in range(8*8):\n",
    "    if grayscale_ahash_image1_list[x]!=grayscale_ahash_image2_list[x]:\n",
    "        distance_hanming= distance_hanming+1\n",
    "print(distance_hanming)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.感知哈希算法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 对图片进行缩放\n",
    "pHash_resize_width = 32\n",
    "pHash_resize_height = 32\n",
    "smaller_phash_img1 = img1.resize((pHash_resize_width, pHash_resize_height))\n",
    "smaller_phash_img2 = img2.resize((pHash_resize_width, pHash_resize_height))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 转换为灰度直方图\n",
    "grayscale_phash_image1 = smaller_phash_img1.convert(\"L\")\n",
    "grayscale_phash_image2 = smaller_phash_img2.convert(\"L\")\n",
    "\n",
    "grayscale_phash_image1_np = np.float32(grayscale_phash_image1)\n",
    "grayscale_phash_image2_np = np.float32(grayscale_phash_image2)\n",
    "\n",
    "# DCT\n",
    "dct_grayscale_phash_image1_np = cv.dct(grayscale_phash_image1_np)\n",
    "dct_grayscale_phash_image2_np = cv.dct(grayscale_phash_image2_np)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "dct_grayscale_phash_image1_np_8_8 = dct_grayscale_phash_image1_np[0:8, 0:8]\n",
    "dct_grayscale_phash_image2_np_8_8 = dct_grayscale_phash_image2_np[0:8, 0:8]\n",
    "#取平均值\n",
    "dct_grayscale_phash_image1_np_8_8_mean = np.mean(dct_grayscale_phash_image1_np_8_8)\n",
    "dct_grayscale_phash_image2_np_8_8_mean = np.mean(dct_grayscale_phash_image2_np_8_8)\n",
    "#比较平均值\n",
    "dct_grayscale_phash_image1_np_8_8_result = dct_grayscale_phash_image1_np_8_8[0:8,0:8]>dct_grayscale_phash_image1_np_8_8_mean\n",
    "dct_grayscale_phash_image2_np_8_8_result = dct_grayscale_phash_image1_np_8_8[0:8,0:8]>dct_grayscale_phash_image2_np_8_8_mean\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "#计算汉明距离\n",
    "distance_hanming_phash = 0\n",
    "distance_hanming_phash_np = dct_grayscale_phash_image1_np_8_8_result^dct_grayscale_phash_image2_np_8_8_result\n",
    "for x in range(8):\n",
    "    for y in range(8):\n",
    "        if distance_hanming_phash_np[x,y] == False:\n",
    "            distance_hanming_phash = distance_hanming_phash+1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.差异哈希算法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "33\n"
     ]
    }
   ],
   "source": [
    "# 对图片进行缩放 9* 8\n",
    "dHash_resize_width = 9\n",
    "dHash_resize_height = 8\n",
    "smaller_dhash_img1 = img1.resize((dHash_resize_width, dHash_resize_height))\n",
    "smaller_dhash_img2 = img2.resize((dHash_resize_width, dHash_resize_height))\n",
    "\n",
    "# 转换为灰度直方图\n",
    "grayscale_dhash_image1 = smaller_dhash_img1.convert(\"L\")\n",
    "grayscale_dhash_image2 = smaller_dhash_img2.convert(\"L\")\n",
    "\n",
    "# 转换为矩阵\n",
    "grayscale_dhash_image1_np = np.float32(grayscale_dhash_image1)\n",
    "grayscale_dhash_image2_np = np.float32(grayscale_dhash_image2)\n",
    "grayscale_dhash_image1_np_result = np.ones((8,8))\n",
    "grayscale_dhash_image2_np_result = np.ones((8,8))\n",
    "# 进行比较\n",
    "for x in range(8):\n",
    "    for y in range(0,8):\n",
    "        if grayscale_dhash_image1_np[x,y] >= grayscale_dhash_image1_np[x,y+1]:\n",
    "            grayscale_dhash_image1_np_result[x,y] = 0\n",
    "        else:\n",
    "            grayscale_dhash_image1_np_result[x,y] = 1\n",
    "\n",
    "for x in range(8):\n",
    "    for y in range(0,8):\n",
    "        if grayscale_dhash_image2_np[x,y] >= grayscale_dhash_image2_np[x,y+1]:\n",
    "            grayscale_dhash_image2_np_result[x,y] = 0\n",
    "        else:\n",
    "            grayscale_dhash_image2_np_result[x,y] = 1\n",
    "\n",
    "distance_hanming_dhash_np = grayscale_dhash_image1_np_result - grayscale_dhash_image2_np_result\n",
    "# 统计非0数\n",
    "distance_hanming_dhash =np.count_nonzero(distance_hanming_dhash_np)\n",
    "print(distance_hanming_dhash)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 直方图交叉核"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4.125\n"
     ]
    }
   ],
   "source": [
    "import math\n",
    "##### 对图片进行缩放\n",
    "histogram_resize_width = 8\n",
    "histogram_resize_height = 8\n",
    "smaller_histogram_img1 = img1.resize((histogram_resize_width, histogram_resize_height))\n",
    "smaller_histogram_img2 = img2.resize((histogram_resize_height, histogram_resize_height))\n",
    "\n",
    "# 转换为灰度直方图\n",
    "grayscale_histogram_image1 = smaller_histogram_img1.convert(\"L\")\n",
    "grayscale_histogram_image2 = smaller_histogram_img2.convert(\"L\")\n",
    "\n",
    "# 转换为一维矩阵\n",
    "grayscale_histogram_image1_np = np.array(grayscale_histogram_image1)\n",
    "grayscale_histogram_image2_np = np.array(grayscale_histogram_image2)\n",
    "grayscale_histogram_image1_np = np.reshape(grayscale_histogram_image1_np,8*8)\n",
    "grayscale_histogram_image2_np = np.reshape(grayscale_histogram_image2_np,8*8)\n",
    "\n",
    "# 构造直方图交叉核\n",
    "histogram_np = []\n",
    "histogram_np_result_v = []\n",
    "histogram_np_result_w = []\n",
    "histogram_np_result = []\n",
    "for x in range(16,36,4):\n",
    "    index = 5 - (36 - x)//4\n",
    "    grayscale_histogram_image1_tuple = np.histogram(grayscale_histogram_image1_np,bins=x,range=(0,255))\n",
    "    grayscale_histogram_image2_tuple = np.histogram(grayscale_histogram_image2_np,bins=x,range=(0,255))\n",
    "    result = grayscale_histogram_image1_tuple[0] * grayscale_histogram_image2_tuple[0]\n",
    "    # 统计非零个数，即为含有相同像素的区域\n",
    "    histogram_np.append(np.count_nonzero(result))\n",
    "# 计算直方图交叉核\n",
    "for x in range(0,4):\n",
    "    histogram_np_result_v.append(histogram_np[x+1]-histogram_np[x])\n",
    "    histogram_np_result_w.append(histogram_np_result_tmp[x] * math.pow(2,(-1)*x))\n",
    "    histogram_np_result.append(histogram_np_result_w[x]* histogram_np_result_v[x])\n",
    "print(sum(histogram_np_result))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [conda root]",
   "language": "python",
   "name": "conda-root-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
